import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import javax.imageio.ImageIO;

// Original sprite cache class author: Kevin Glass
 
public class SpriteStorage {
        /** The single instance of this class */
        private static SpriteStorage single = new SpriteStorage();
        /**
         * Get the single instance of this class 
         * 
         * @return The single instance of this class
         */
        public static SpriteStorage get() {
                return single;
        }
        /** The cached sprite map, from reference to sprite instance */
        private HashMap<String, Image> spriteImages = new HashMap<String, Image>();
        /**
         * Retrieve a sprite from the store
         * 
         * @param ref The reference to the image to use for the sprite
         * @return A sprite instance containing an accelerate image of the request reference
         */
        public Image getSprite(String ref) {
                // if we've already got the sprite in the cache
                // then just return the existing version
                if (spriteImages.get(ref) != null) {
                        return (Image) spriteImages.get(ref);       
                }
                // otherwise, go away and grab the sprite from the resource
                // loader
                BufferedImage sourceImage = null;
                try {
                        // The ClassLoader.getResource() ensures we get the sprite
                        // from the appropriate place, this helps with deploying the game
                        // with things like webstart. You could equally do a file look
                        // up here..
                        URL url = this.getClass().getClassLoader().getResource("images/"+ref);
                        if (url == null) {
                                fail("Can't find ref: "+ref);
                        }
                        // use ImageIO to read the image in
                        sourceImage = ImageIO.read(url);
                } catch (IOException e) {
                        fail("Failed to load: "+ref);
                }
                // create an accelerated image of the right s.ize to store our sprite in
                GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
                Image image = gc.createCompatibleImage(sourceImage.getWidth(),sourceImage.getHeight(),Transparency.TRANSLUCENT);
                // draw our source image into the accelerated image
                image.getGraphics().drawImage(sourceImage,0,0,null);
                // create a sprite, add it the cache then return it
                spriteImages.put(ref,image);
                return image;
        }
        /**
         * Utility method to handle resource loading failure
         * 
         * @param message The message to display on failure
         */
        private void fail(String message) {
                System.err.println(message);
                System.exit(0);
        }
}
